#!/usr/bin/env node
const path = require('path')
const Koa = require('koa')
const send = require('koa-send')
const compilerSFC = require('@vue/compiler-sfc')
const { streamToString, stringToStream } = require('./utils/index.js')


const koa = new Koa()

// 3.将以/@modules开头的路径重新指向node_modules目录的模块文件
koa.use(async (ctx, next) => {
    if (ctx.path.startsWith('/@modules/')) {
        const moduleName = ctx.path.substr(10)
        const pkgPath = path.join(process.cwd(), 'node_modules', moduleName, 'package.json')
        const pkg = require(pkgPath)
        ctx.path = path.join('/node_modules/', moduleName, pkg.module)
    }
    await next()
})

// 1. 显示静态服务器
koa.use(async (ctx, next) => {
    await send(ctx, ctx.path, { root: process.cwd(), index: 'index.html' });
    await next()
})

// 4.1 将以vue结尾的文件响应格式改成application/javascript, 然后输出流
// 4.2 将没有参数的vue文件解析js内容（因为JavaScript文件）
// 4.3 将有参数的vue文件解析template内容返回解析后的内容
koa.use(async (ctx, next) => {
    if (ctx.path.endsWith('.vue')) {
        const contents = await streamToString(ctx.body)
        const { descriptor } = compilerSFC.parse(contents)
        let code
        if (!ctx.query.type) {
            code = descriptor.script.content
            code = code.replace(/export\s+default\s+/g, 'const __script = ')
            code += `
                import { render as __render } from "${ctx.path}?type=template"
                __script.render = __render
                export default __script
                `
        } else if (ctx.query.type === 'template') {
            const templateRender = compilerSFC.compileTemplate({
                source: descriptor.template.content
            })
            code = templateRender.code

        }
        ctx.type = 'application/javascript'
        ctx.body = stringToStream(code) 
    }
    await next()
})


// 2.处理javascript文件中的第三方路径,再返回
// 2.1 处理vue文件里面的process变量
koa.use(async (ctx, next) => {
    if (ctx.type === 'application/javascript') {
        const content = await streamToString(ctx.body)
        ctx.body = content
                    .replace(/(from\s+['"])(?![\.\/])/g, '$1/@modules/')
                    .replace(/process\.env\.NODE_ENV/g, '"development"')
    }
    await next()
})

koa.listen('3000', () => {
    console.log('Listening on http://localhost:3000')
})